package com.yanshaohui.controller;

import com.yanshaohui.bean.Person;
import org.jboss.logging.Logger;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Created by TS-Ysh on 2018-05-14.
 */
@RestController
public class ReactPersonController {

    private final Logger logger = Logger.getLogger(getClass());

    @GetMapping("/person/{id}")
    public Mono<Person> getOnePerson(@PathVariable("id") Long id){
        return Mono.just(new Person(id,"严少辉",1,"大寨路",35)).delayElement(Duration.ofMillis(300));

//        return Mono.fromSupplier(()->{
//            return new Person(id,"严少辉",1,"大寨路",35);
//        });
    }

    /**
     * springmvcweb方式，和上面React方式比较一下性能
     * @param id
     * @return
     */
    @GetMapping("/person2/{id}")
    public Person getOnePerson2(@PathVariable("id") Long id){

        try {
            Thread.sleep(300);
            System.out.println("I am alive:" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new Person(id,"严少辉",1,"大寨路",35);
    }

    @GetMapping("/persons")
    public Flux<Person> getAllPerson(){
        return Flux.fromStream(Stream.iterate(new Person(2L,"谢晓亮",1,"丈八六路",34),a->new Person(a.getId()+1L,"谢晓亮" + a.getId() + "x",1,"丈八六路",34)).limit(50));

    }


    @GetMapping("/test1")
    public Mono<ServerResponse> test1() {
        Map<String, String> result = new HashMap<>();
        result.put("message", "successful");
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .body(BodyInserters.fromObject(result));

    }

    @GetMapping("/people")
    Flux<String> test2() {
        return Flux.fromStream(Stream.iterate(1,a -> a+a).map(a->a.toString() + ",").limit(20));
    }

    /**
     * CMD下测服务器推送，失败了。。。原因不明
     * curl http://localhost:8087/test3
     *
     * 网上样例是用RouterFunction方式注册路由，仅此差别。Reactive包装@RequestParam参数也不行。ServerRequest参数也不行。是不是注解路由方式实现不全啊。
     * @return
     */
    @GetMapping("/test3")
    public Mono<ServerResponse> test3() {
        return ServerResponse.ok()
                .contentType(MediaType.TEXT_EVENT_STREAM)
                .body( Flux.interval(Duration.ofSeconds(1)).map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date())),
                        String.class);

    }
}
